<template>
  <UModal v-model="isOpen" :ui="{ width: 'max-w-5xl', container: 'flex items-center justify-center min-h-screen' }">
    <div class="relative bg-black rounded-xl overflow-hidden">
      <!-- 顶部工具栏 -->
      <div class="absolute top-0 left-0 right-0 z-10 bg-gradient-to-b from-black/70 to-transparent px-4 py-3 flex justify-between items-center">
        <div class="text-white font-medium truncate max-w-md">
          {{ image?.title || '图片预览' }}
        </div>
        <div class="flex items-center space-x-3">
          <UButton
            color="white"
            variant="ghost"
            icon="i-heroicons-arrow-down-tray"
            @click="downloadImage"
            class="text-white hover:text-white hover:bg-white/20"
          />
          <UButton
            color="white"
            variant="ghost"
            icon="i-heroicons-arrows-pointing-out"
            @click="toggleFullScreen"
            class="text-white hover:text-white hover:bg-white/20"
          />
          <UButton
            color="white"
            variant="ghost"
            icon="i-heroicons-x-mark"
            @click="close"
            class="text-white hover:text-white hover:bg-white/20"
          />
        </div>
      </div>

      <!-- 图片容器 -->
      <div 
        class="relative flex items-center justify-center min-h-[50vh] max-h-[80vh] overflow-hidden"
        ref="imageContainer"
        @wheel="handleZoom"
        @mousedown="startPan"
        @mousemove="pan"
        @mouseup="endPan"
        @mouseleave="endPan"
        @touchstart="startPinchZoom"
        @touchmove="pinchZoom"
        @touchend="endPinchZoom"
      >
        <!-- 加载状态 -->
        <div v-if="isLoading" class="absolute inset-0 flex items-center justify-center bg-black/30 z-10">
          <div class="flex flex-col items-center">
            <UIcon name="i-heroicons-arrow-path" class="h-10 w-10 animate-spin text-white mb-2" />
            <span class="text-white text-sm">加载中...</span>
          </div>
        </div>
        
        <!-- 加载错误 -->
        <div v-if="loadError" class="absolute inset-0 flex items-center justify-center bg-black/30 z-10">
          <div class="flex flex-col items-center text-center px-4">
            <UIcon name="i-heroicons-exclamation-circle" class="h-10 w-10 text-red-500 mb-2" />
            <span class="text-white text-sm mb-3">图片加载失败</span>
            <UButton size="sm" color="white" @click="retryLoad">重试</UButton>
          </div>
        </div>
        
        <img
          v-if="image && !loadError"
          :src="image.img_url"
          :alt="image.title"
          class="max-w-full max-h-full object-contain transition-transform duration-200"
          :style="{
            transform: `scale(${scale}) translate(${translateX}px, ${translateY}px)`,
            cursor: isPanning ? 'grabbing' : 'grab'
          }"
          @load="handleImageLoaded"
          @error="handleImageError"
          @dblclick="resetZoom"
        />
      </div>

      <!-- 底部工具栏 -->
      <div class="absolute bottom-0 left-0 right-0 z-10 bg-gradient-to-t from-black/70 to-transparent px-4 py-3 flex justify-center items-center">
        <div class="flex items-center space-x-4">
          <UButton
            color="white"
            variant="ghost"
            icon="i-heroicons-minus"
            @click="zoomOut"
            class="text-white hover:text-white hover:bg-white/20"
          />
          <div class="text-white text-sm">
            {{ Math.round(scale * 100) }}%
          </div>
          <UButton
            color="white"
            variant="ghost"
            icon="i-heroicons-plus"
            @click="zoomIn"
            class="text-white hover:text-white hover:bg-white/20"
          />
          <UButton
            color="white"
            variant="ghost"
            icon="i-heroicons-arrow-path"
            @click="resetZoom"
            class="text-white hover:text-white hover:bg-white/20"
          />
        </div>
      </div>
    </div>
  </UModal>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onUnmounted } from 'vue'

interface Image {
  id: number
  title: string
  content: string
  user_id: number
  img_url: string
  views_count: number
  download_count: number
  created_at: number
}

const props = defineProps<{
  modelValue: boolean
  image: Image | null
}>()

const emit = defineEmits(['update:modelValue'])

const isOpen = ref(props.modelValue)
const scale = ref(1)
const translateX = ref(0)
const translateY = ref(0)
const isPanning = ref(false)
const startX = ref(0)
const startY = ref(0)
const imageContainer = ref<HTMLElement | null>(null)
const isLoading = ref(false)
const loadError = ref(false)

// 监听modelValue变化
watch(() => props.modelValue, (newVal) => {
  isOpen.value = newVal
  if (newVal) {
    // 重置缩放和位置
    resetZoom()
    // 添加键盘事件监听
    addKeyboardListeners()
    // 重置加载状态
    isLoading.value = true
    loadError.value = false
  } else {
    removeKeyboardListeners()
  }
})

// 监听image变化
watch(() => props.image, () => {
  if (props.image) {
    isLoading.value = true
    loadError.value = false
  }
})

// 监听isOpen变化
watch(() => isOpen.value, (newVal) => {
  emit('update:modelValue', newVal)
  if (!newVal) {
    removeKeyboardListeners()
  }
})

// 关闭预览
const close = () => {
  isOpen.value = false
}

// 图片加载处理
const handleImageLoaded = () => {
  isLoading.value = false
  loadError.value = false
}

const handleImageError = () => {
  isLoading.value = false
  loadError.value = true
  console.error('图片加载失败:', props.image?.img_url)
}

const retryLoad = () => {
  if (props.image) {
    isLoading.value = true
    loadError.value = false
    // 通过添加时间戳强制重新加载图片
    const imgElement = imageContainer.value?.querySelector('img')
    if (imgElement) {
      const currentSrc = imgElement.src
      imgElement.src = ''
      setTimeout(() => {
        imgElement.src = currentSrc.includes('?') 
          ? `${currentSrc}&t=${Date.now()}` 
          : `${currentSrc}?t=${Date.now()}`
      }, 100)
    }
  }
}

// 缩放相关函数
const zoomIn = () => {
  scale.value = Math.min(scale.value + 0.2, 5)
}

const zoomOut = () => {
  scale.value = Math.max(scale.value - 0.2, 0.2)
}

const resetZoom = () => {
  scale.value = 1
  translateX.value = 0
  translateY.value = 0
}

const handleZoom = (e: WheelEvent) => {
  e.preventDefault()
  if (e.deltaY < 0) {
    zoomIn()
  } else {
    zoomOut()
  }
}

// 平移相关函数
const startPan = (e: MouseEvent) => {
  isPanning.value = true
  startX.value = e.clientX - translateX.value
  startY.value = e.clientY - translateY.value
}

const pan = (e: MouseEvent) => {
  if (isPanning.value) {
    translateX.value = e.clientX - startX.value
    translateY.value = e.clientY - startY.value
  }
}

const endPan = () => {
  isPanning.value = false
}

// 触摸缩放相关函数
let initialDistance = 0
let initialScale = 1

const startPinchZoom = (e: TouchEvent) => {
  if (e.touches.length === 2) {
    initialDistance = Math.hypot(
      e.touches[0].clientX - e.touches[1].clientX,
      e.touches[0].clientY - e.touches[1].clientY
    )
    initialScale = scale.value
  }
}

const pinchZoom = (e: TouchEvent) => {
  if (e.touches.length === 2) {
    const currentDistance = Math.hypot(
      e.touches[0].clientX - e.touches[1].clientX,
      e.touches[0].clientY - e.touches[1].clientY
    )
    
    const ratio = currentDistance / initialDistance
    scale.value = Math.min(Math.max(initialScale * ratio, 0.2), 5)
  }
}

const endPinchZoom = () => {
  initialDistance = 0
}

// 全屏切换
const toggleFullScreen = () => {
  if (!document.fullscreenElement) {
    imageContainer.value?.requestFullscreen().catch(err => {
      console.error(`全屏模式错误: ${err.message}`)
    })
  } else {
    document.exitFullscreen()
  }
}

// 下载图片
const downloadImage = () => {
  if (!props.image) return
  
  const link = document.createElement('a')
  link.href = props.image.img_url
  link.download = props.image.title || 'image'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

// 键盘事件处理
const handleKeyDown = (e: KeyboardEvent) => {
  if (e.key === 'Escape') {
    close()
  } else if (e.key === '+' || e.key === '=') {
    zoomIn()
  } else if (e.key === '-') {
    zoomOut()
  } else if (e.key === '0') {
    resetZoom()
  } else if (e.key === 'f') {
    toggleFullScreen()
  } else if (e.key === 'd') {
    downloadImage()
  } else if (e.key === 'r' && loadError.value) {
    retryLoad()
  }
}

const addKeyboardListeners = () => {
  window.addEventListener('keydown', handleKeyDown)
}

const removeKeyboardListeners = () => {
  window.removeEventListener('keydown', handleKeyDown)
}

onMounted(() => {
  if (isOpen.value) {
    addKeyboardListeners()
  }
})

onUnmounted(() => {
  removeKeyboardListeners()
})
</script>

<style scoped>
.max-h-[80vh] {
  max-height: 80vh;
}

/* 添加一些过渡效果 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>
